﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using DS.SludgeEngine.Base;

namespace DS.SludgeEngine.Drawing
{
    public class Drawing2DManager : DrawableGameComponent, IDisposable, IDrawing2DManager
    {
        private List<IShape> shapes = new List<IShape>();
        private List<IShape> nonPersistentShapes = new List<IShape>();
        private VertexDeclaration vertexDecl;
        private List<VertexPositionColor> buffer = new List<VertexPositionColor>();
        private BasicEffect effect;
        private int numberOfPoints = 0;

        public Drawing2DManager(Game game)
            : base(game)
        {

        }
        public IShape AddRectangle(Vector2 start, Vector2 end, Color color, bool persistant)
        {
            IShape newShape = new Rectangle(new Vector3(start.X, start.Y, 0)
                , new Vector3(end.X, end.Y, 0), color);
            
            if (persistant)
            {
                shapes.Add(newShape);
            }
            else
            {
                nonPersistentShapes.Add(newShape);
            }
            return newShape;
        }
        public void RemoveShape(IShape newShape)
        {
            shapes.Remove(newShape);
        }
        public override void Initialize()
        {
            IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)base.Game.Services.GetService(typeof(IGraphicsDeviceService));

            vertexDecl = new VertexDeclaration(graphicsService.GraphicsDevice, VertexPositionColor.VertexElements);
            effect = new BasicEffect(graphicsService.GraphicsDevice, null);// = base.Game.Content.Load<Effect>(@"shaders\simple");


            effect.VertexColorEnabled = true;

            // projection uses CreateOrthographicOffCenter to create 2d projection
            // matrix with 0,0 in the upper left.
            effect.Projection = Matrix.CreateOrthographicOffCenter
                (0, graphicsService.GraphicsDevice.Viewport.Width,
                graphicsService.GraphicsDevice.Viewport.Height, 0,
                0, 1);




            base.Initialize();
        }

        public void UpdateScreen()
        {
            IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)base.Game.Services.GetService(typeof(IGraphicsDeviceService));

            effect.Projection = Matrix.CreateOrthographicOffCenter
                (0, graphicsService.GraphicsDevice.Viewport.Width,
                graphicsService.GraphicsDevice.Viewport.Height, 0,
                0, 1);

        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public override void Draw(GameTime time)
        {

            List<IShape> totalShapes = new List<IShape>();
            totalShapes.AddRange(shapes);
            totalShapes.AddRange(nonPersistentShapes);
            if (totalShapes.Count != 0)
            {
                numberOfPoints = 0;

                foreach (IShape currentShape in totalShapes)
                {
                    foreach (VertexPositionColor currentVertex in currentShape.Vertices)
                    {
                        buffer.Add(currentVertex);
                        numberOfPoints++;
                    }
                }

                if (buffer.Count > 0)
                {

                    IGraphicsDeviceService graphicsService = (IGraphicsDeviceService)base.Game.Services.GetService(typeof(IGraphicsDeviceService));
                    ICameraManager camera = (ICameraManager)base.Game.Services.GetService(typeof(ICameraManager));

                    GraphicsDevice device = graphicsService.GraphicsDevice;

                    device.VertexDeclaration = vertexDecl;
                    
                    effect.Begin();
                    effect.Techniques[0].Passes[0].Begin();

                    VertexPositionColor[] vertices = buffer.ToArray();
                    device.DrawUserPrimitives<VertexPositionColor>(PrimitiveType.LineList, vertices, 0, vertices.Length / 2);

                    effect.Techniques[0].Passes[0].End();
                    effect.End();
                }
            }
            nonPersistentShapes.Clear();
            buffer.Clear();
        }

        protected virtual void Dispose(bool all)
        {
            if (vertexDecl != null)
            {
                vertexDecl.Dispose();
                vertexDecl = null;
            }
        }

        public virtual void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}
